package com.ruoyi.web.controller.app;

import com.ruoyi.app.domain.AppUser;
import com.ruoyi.app.domain.AppScenicSpot;
import com.ruoyi.app.domain.AppTravelGuide;
import com.ruoyi.app.domain.AppHotel;
import com.ruoyi.app.domain.AppArea;
import com.ruoyi.app.service.IAppUserService;
import com.ruoyi.app.service.IAppScenicSpotService;
import com.ruoyi.app.service.IAppTravelGuideService;
import com.ruoyi.app.service.IAppHotelService;
import com.ruoyi.app.service.IAppAreaService;
import com.ruoyi.common.annotation.Anonymous;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.utils.file.FileUploadUtils;
import com.ruoyi.common.utils.file.MimeTypeUtils;
import com.ruoyi.common.utils.uuid.UUID;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.io.IOException;

import static com.ruoyi.common.utils.ServletUtils.getRequest;

/**
 * 微信小程序接口
 */
@RestController
@RequestMapping("/wx")
public class WxController extends BaseController {

    @Autowired
    private IAppUserService appUserService;

    @Autowired
    private RedisCache redisCache;

    @Autowired
    private IAppScenicSpotService scenicSpotService;

    @Autowired
    private IAppTravelGuideService appTravelGuideService;

    @Autowired
    private IAppHotelService appHotelService;

    @Autowired
    private IAppAreaService appAreaService;

    @Autowired
    private RuoYiConfig ruoYiConfig;

    // Redis中保存用户Token信息的key前缀
    private static final String APP_TOKEN_PREFIX = "app_token:";

    // token有效期（单位：小时）
    private static final int TOKEN_EXPIRE_HOURS = 24;

    /**
     * 用户名、密码注册接口
     */
    @Anonymous
    @PostMapping("/appUser/register")
    public AjaxResult register(@RequestBody AppUser user) {
        // 校验用户名是否已存在
        AppUser existUser = new AppUser();
        existUser.setUsername(user.getUsername());
        if (appUserService.selectAppUserList(existUser).size() > 0) {
            return AjaxResult.error("用户名已存在");
        }

        // 设置默认值
        user.setNickname(user.getNickname());
        user.setStatus("0");  // 0正常 1停用

        // 调用服务层添加用户
        return toAjax(appUserService.insertAppUser(user));
    }

    /**
     * 用户名、密码登录接口
     */
    @Anonymous
    @PostMapping("/appUser/login")
    public AjaxResult login(@RequestBody AppUser user) {
        // 根据用户名查询用户
        AppUser queryUser = new AppUser();
        queryUser.setUsername(user.getUsername());
        queryUser.setPassword(user.getPassword());

        // 验证用户名和密码
        AppUser loginUser = appUserService.selectAppUserList(queryUser).stream().findFirst().orElse(null);
        if (loginUser == null) {
            return AjaxResult.error("用户名或密码错误");
        }

        // 检查用户状态
        if ("1".equals(loginUser.getStatus())) {
            return AjaxResult.error("账号已被停用");
        }

        // 生成token
        String token = UUID.fastUUID().toString();

        // 将用户信息存入Redis，设置过期时间
        String tokenKey = APP_TOKEN_PREFIX + token;
        redisCache.setCacheObject(tokenKey, loginUser, TOKEN_EXPIRE_HOURS, TimeUnit.HOURS);

        // 构建返回结果
        Map<String, Object> result = new HashMap<>();
        result.put("token", token);
        result.put("user", loginUser);

        // 返回用户信息和token
        return AjaxResult.success("登录成功", result);
    }

    /**
     * 退出登录
     */
    @Anonymous
    @PostMapping("/appUser/logout")
    public AjaxResult logout(@RequestHeader("Authorization") String token) {
        if (token != null && token.startsWith("Bearer ")) {
            token = token.substring(7);
            // 从Redis中删除token
            String tokenKey = APP_TOKEN_PREFIX + token;
            redisCache.deleteObject(tokenKey);
        }
        return AjaxResult.success("退出成功");
    }

    /**
     * 获取首页景区列表
     */
    @Anonymous
    @GetMapping("/home/spots")
    public AjaxResult getHomeSpots() {
        // 查询景区列表
        AppScenicSpot querySpot = new AppScenicSpot();
        // 可以设置一些筛选条件，比如只查询推荐的景区等
        List<AppScenicSpot> spotList = scenicSpotService.selectAppScenicSpotList(querySpot);
        return AjaxResult.success(spotList);
    }

    /**
     * 获取景点详情
     */
    @Anonymous
    @GetMapping("/spots/{spotId}")
    public AjaxResult getSpotDetail(@PathVariable("spotId") Long spotId) {
        AppScenicSpot spot = scenicSpotService.selectAppScenicSpotBySpotId(spotId);
        if (spot == null) {
            return AjaxResult.error("景点不存在");
        }
        return AjaxResult.success(spot);
    }

    /**
     * 搜索景点
     */
    @Anonymous
    @GetMapping("/spots/search")
    public AjaxResult searchSpots(String keyword) {
        AppScenicSpot querySpot = new AppScenicSpot();
        // 当关键词不为空时才设置搜索条件
        if (StringUtils.isNotBlank(keyword)) {
            querySpot.setSpotName(keyword);
            // 可以扩展搜索条件，比如地址、描述等
            // querySpot.setAddress(keyword);
            // querySpot.setDescription(keyword);
        }
        List<AppScenicSpot> spotList = scenicSpotService.selectAppScenicSpotList(querySpot);
        return AjaxResult.success(spotList);
    }

    /**
     * 获取攻略列表
     */
    @Anonymous
    @GetMapping("/guide/list")
    public AjaxResult getGuideList(Long spotId) {
        AppTravelGuide queryGuide = new AppTravelGuide();
        if (spotId != null) {
            queryGuide.setSpotId(spotId);
        }
        List<AppTravelGuide> guideList = appTravelGuideService.selectAppTravelGuideList(queryGuide);
        return AjaxResult.success(guideList);
    }

    /**
     * 获取攻略详情
     */
    @Anonymous
    @GetMapping("/guide/{guideId}")
    public AjaxResult getGuideDetail(@PathVariable("guideId") Long guideId) {
        AppTravelGuide guide = appTravelGuideService.selectAppTravelGuideByGuideId(guideId);
        if (guide == null) {
            return AjaxResult.error("攻略不存在");
        }
        return AjaxResult.success(guide);
    }

    /**
     * 获取酒店列表
     */
    @Anonymous
    @GetMapping("/hotel/list")
    public AjaxResult getHotelList(String keyword) {
        AppHotel queryHotel = new AppHotel();
        if (StringUtils.isNotBlank(keyword)) {
            queryHotel.setHotelName(keyword);
        }
        List<AppHotel> hotelList = appHotelService.selectAppHotelList(queryHotel);
        return AjaxResult.success(hotelList);
    }

    /**
     * 获取酒店详情
     */
    @Anonymous
    @GetMapping("/hotel/{hotelId}")
    public AjaxResult getHotelDetail(@PathVariable("hotelId") Long hotelId) {
        AppHotel hotel = appHotelService.selectAppHotelByHotelId(hotelId);
        if (hotel == null) {
            return AjaxResult.error("酒店不存在");
        }
        return AjaxResult.success(hotel);
    }

    /**
     * 修改用户信息
     */
    @Anonymous
    @PostMapping("/appUser/update")
    public AjaxResult updateUserInfo(@RequestBody AppUser user) {
        // 从token中获取用户ID
        String token = getRequest().getHeader("Authorization");
        if (token != null && token.startsWith("Bearer ")) {
            token = token.substring(7);
            AppUser loginUser = redisCache.getCacheObject(APP_TOKEN_PREFIX + token);
            if (loginUser != null) {
                user.setUserId(loginUser.getUserId());
                // 不允许修改用户名和密码
                user.setUsername(null);
                user.setPassword(null);
                int rows = appUserService.updateAppUser(user);
                if (rows > 0) {
                    // 更新Redis中的用户信息
                    loginUser = appUserService.selectAppUserByUserId(loginUser.getUserId());
                    redisCache.setCacheObject(APP_TOKEN_PREFIX + token, loginUser, TOKEN_EXPIRE_HOURS, TimeUnit.HOURS);
                    return AjaxResult.success(loginUser);
                }
                return AjaxResult.error("修改用户信息失败");
            }
        }
        return AjaxResult.error("用户未登录");
    }

    /**
     * 上传图片
     */
    @Anonymous
    @PostMapping("/common/upload")
    public AjaxResult uploadFile(MultipartFile file) throws IOException {
        try {
            // 检查文件类型
            String extension = FileUploadUtils.getExtension(file);

            // 限制文件大小（2MB）
            long size = file.getSize();
            if (size > 2 * 1024 * 1024) {
                return AjaxResult.error("文件大小不能超过2MB");
            }

            // 上传文件路径
            String filePath = RuoYiConfig.getAvatarPath();
            String avatar = FileUploadUtils.upload(RuoYiConfig.getAvatarPath(), file, MimeTypeUtils.IMAGE_EXTENSION);

            AjaxResult ajax = AjaxResult.success();
            ajax.put("avatar", avatar);
            return ajax;
        } catch (Exception e) {
            return AjaxResult.error(e.getMessage());
        }
    }

    /**
     * 获取区域列表
     */
    @Anonymous
    @GetMapping("/area/list")
    public AjaxResult getAreaList() {
        List<AppArea> areaList = appAreaService.selectAppAreaList(new AppArea());
        return AjaxResult.success(areaList);
    }

    /**
     * 获取景点列表
     */
    @Anonymous
    @GetMapping("/spots/list")
    public AjaxResult getSpotList(String name, Long areaId) {
        AppScenicSpot querySpot = new AppScenicSpot();
        if (StringUtils.isNotBlank(name)) {
            querySpot.setSpotName(name);
        }
        if (areaId != null) {
            querySpot.setAreaId(areaId);
        }
        List<AppScenicSpot> spotList = scenicSpotService.selectAppScenicSpotList(querySpot);
        return AjaxResult.success(spotList);
    }
}
